package com.blm.service.impl;

import com.blm.common.constants.CacheConstant;
import com.blm.common.constants.ExceptionConstant;
import com.blm.dto.StoreCreateDTO;
import com.blm.dto.StoreStatusUpdateDTO;
import com.blm.dto.StoreUpdateDTO;
import com.blm.entity.Store;
import com.blm.exception.CommonException;
import com.blm.repository.StoreRepository;
import com.blm.service.MerchantStoreService;
import com.blm.service.StoreService;
import com.blm.vo.StoreVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class MerchantStoreServiceImpl extends BaseService implements MerchantStoreService {

    @Autowired
    private StoreRepository storeRepository;

    @Autowired
    private StoreService storeService;

    @Override
    @Transactional
    @CacheEvict(value = CacheConstant.STORE_LIST_MERCHANT, key = "#merchantId")
    public StoreVO createStore(Long merchantId, StoreCreateDTO dto) {
        Store store = new Store();
        BeanUtils.copyProperties(dto, store);
        store.setMerchantId(merchantId);
        store.setStatus(Store.StoreStatus.PENDING); // 待审核
        store.setRating(BigDecimal.valueOf(5.0));
        store.setCreatedAt(LocalDateTime.now());
        store.setUpdatedAt(LocalDateTime.now());
        int count = storeRepository.insertStore(store);
        if (count != 1) {
            throw new CommonException(ExceptionConstant.STORE_CREATE_FAILED);
        }

        StoreVO vo = new StoreVO();
        BeanUtils.copyProperties(store, vo);
        return vo;
    }

    @Override
    @Transactional
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.STORE, key = "#storeId"), // 清除单个店铺缓存
            @CacheEvict(value = CacheConstant.STORE_LIST_USER, allEntries = true), // 清除店铺列表缓存
            @CacheEvict(value = CacheConstant.STORE_RECOMMEND, allEntries = true), // 清除推荐店铺缓存
            @CacheEvict(value = CacheConstant.STORE_DETAIL, key = "#storeId"), // 清除店铺详情缓存
            @CacheEvict(value = CacheConstant.STORE_LIST_MERCHANT, key = "#merchantId") // 清除商家店铺列表缓存
    })
    public StoreVO updateStore(Long merchantId, Long storeId, StoreUpdateDTO dto) {
        Store store = storeService.getStoreById(storeId);
        if (!store.getMerchantId().equals(merchantId)) {
            throw new CommonException(ExceptionConstant.STORE_UNAUTHORIZED);
        }
        BeanUtils.copyProperties(dto, store);
        store.setUpdatedAt(LocalDateTime.now());

        // 如果是 SUSPENDED 状态，更新为 PENDING
        if(store.getStatus() == Store.StoreStatus.SUSPENDED){
            store.setStatus(Store.StoreStatus.PENDING);
        }

        int count = storeRepository.updateStore(store);
        if (count != 1) {
            throw new CommonException(ExceptionConstant.STORE_UPDATE_FAILED);
        }
        StoreVO vo = new StoreVO();
        BeanUtils.copyProperties(store, vo);
        return vo;
    }

    @Override
    @Transactional
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.STORE, key = "#storeId"), // 清除单个店铺缓存
            @CacheEvict(value = CacheConstant.STORE_LIST_USER, allEntries = true), // 清除店铺列表缓存
            @CacheEvict(value = CacheConstant.STORE_RECOMMEND, allEntries = true), // 清除推荐店铺缓存
            @CacheEvict(value = CacheConstant.STORE_DETAIL, key = "#storeId"), // 清除店铺详情缓存
            @CacheEvict(value = CacheConstant.STORE_LIST_MERCHANT, key = "#merchantId") // 清除商家店铺列表缓存
    })
    public void updateStatus(Long merchantId, Long storeId, StoreStatusUpdateDTO dto) {
        Store store = storeService.getStoreById(storeId);
        if (!store.getMerchantId().equals(merchantId)) {
            throw new CommonException(ExceptionConstant.STORE_UNAUTHORIZED);
        }
        // 商家自己只能更改 OPEN 或 CLOSED 状态
        if (store.getStatus() != Store.StoreStatus.OPEN && store.getStatus() != Store.StoreStatus.CLOSED) {
            throw new CommonException(ExceptionConstant.REQ_PARAM_ERROR);
        }
        storeRepository.updateStatus(storeId, merchantId, dto.getStoreStatus(), LocalDateTime.now());
    }

    @Override
    @Cacheable(value = CacheConstant.STORE_LIST_MERCHANT, key = "#merchantId")
    public List<StoreVO> listMerchantStores(Long merchantId) {
        List<Store> stores = storeRepository.findByMerchantId(merchantId);
        return entity2VO(stores, StoreVO.class);
    }

    @Override
    public StoreVO getStoreById(Long merchantId, Long storeId) {

        List<Store> stores = storeRepository.findByMerchantId(merchantId);
        List<StoreVO> storeVOs = entity2VO(stores, StoreVO.class);
        StoreVO vo = new StoreVO();
        for (StoreVO storeVO : storeVOs){
            if (storeVO.getId().equals(storeId)){
                BeanUtils.copyProperties(storeVO, vo);
                return vo;
            }
        }
        throw new CommonException(ExceptionConstant.STORE_NOT_FOUND);
    }
}